//****************************
//** CSpriteLow
//**
//** Low-Level sprite class
//**
//****************************

#include "stdafx.h"
#include "CImageHigh.h"
#include "CSpriteLow.h"


CSpriteLow::CSpriteLow():CImageHigh()
{
    Init();
}

CSpriteLow::CSpriteLow(HDC hdc):CImageHigh(hdc)
{
    Init();
}

void CSpriteLow::Init()
{
    m_X_Loc = 0;
    m_Y_Loc = 0;
    m_X_Dir = 1;
    m_Y_Dir = 1;
    m_X_Spd = 1;
    m_Y_Spd = 1;

    m_bUnderSaved = FALSE;
    m_bAlive = FALSE;

    m_DestRect = new RECT;
    m_Rect1 = new RECT;
    m_Rect2 = new RECT;

	m_bAutoDraw = TRUE;

	m_iShrinkX=0; m_iShrinkY=0;

	m_iZOrder=0;

	m_bTileCollisionsOn = TRUE;

	m_bShouldErase = TRUE;

	m_iStoreVelocityIncrement = 1;	// update position with velocity every 1 frame
	m_iStoreVelocityCurrentIncrement = 1;
}


CSpriteLow::~CSpriteLow()
{
	DeleteUnder();
    delete m_DestRect;
    delete m_Rect1;
    delete m_Rect2;
}

void CSpriteLow::DeleteUnder() {
	int iRetVal;
	if (m_bUnderSaved) {
		SelectObject(m_hdcUnder, m_hUnderOld);
		iRetVal = DeleteObject(m_hUnder);
		iRetVal = GetLastError();
	    iRetVal = DeleteDC(m_hdcUnder);
		m_bUnderSaved = FALSE;
	}
	return;
}

BOOL CSpriteLow::SaveUnder(HDC hdc, int iXOffset, int iYOffset)
{
	// Save the background data below the sprite for later "erasing"
	// x and y offsets are really only used for scrolling situations only
    if (!m_bUnderSaved)
    {
        m_hUnder = CreateCompatibleBitmap(hdc, ImageWidth(), ImageHeight());
        if (m_hUnder == NULL)
            return FALSE;

        m_hdcUnder = CreateCompatibleDC(hdc);
        if (m_hdcUnder == NULL)
            return FALSE;

		// *ACK* was SelectObject call
        m_hUnderOld = SelectBitmap(m_hdcUnder, m_hUnder);
        
		// *ACK* was here moved to destructor
		// DeleteObject(m_hUnder);
        
		m_bUnderSaved = TRUE;
    }

    if (m_hdcUnder != 0 && hdc != 0)
        BitBlt(m_hdcUnder, 0, 0, ImageWidth(), ImageHeight(), hdc, (int) GetX()+iXOffset, (int) GetY()+iYOffset, SRCCOPY);

    return TRUE;
}

BOOL CSpriteLow::SaveUnder(HDC hdc)
{
	// wrap the SaveUnder function for non-scrolling apps
	return SaveUnder(hdc,0,0);
}

BOOL CSpriteLow::RestoreUnder(HDC hdc)
{
	// "erase" the sprite by restoring the saved background
    if (m_hdcUnder != 0 && hdc != 0)
        BitBlt(hdc, (int) GetX(), (int) GetY(), ImageWidth(), ImageHeight(), m_hdcUnder, 0, 0, SRCCOPY);
    else
        return FALSE;

    return TRUE;
}


BOOL CSpriteLow::TransBlit(COLORREF clrTrans)
{
	// copy the sprite to default context transparently
    return CImageHigh::TransBlit((int) GetX(), (int) GetY(), clrTrans);
}

BOOL CSpriteLow::BitBlit()
{
	// copy the sprite to default DC
    return CImageHigh::BitBlit((int) GetX(), (int) GetY());
}

BOOL CSpriteLow::BitBlit(HDC hdc)
{
	// copy the sprite to a specific DC
    return CImageHigh::BitBlit(hdc, (int) GetX(), (int) GetY());
}

BOOL CSpriteLow::StretchBlit(int dx, int dy)
{
	// copy and scale the sprite to a specific DC
    return CImageHigh::StretchBlit((int) GetX(), (int) GetY(), dx, dy);
}

BOOL CSpriteLow::Intersected(CSpriteLow *Sprite, POINT &pt)
{
	// Checks for collision with another sprite
	// pt is filled with center of collision
    RECT rt;

    if (Intersected(Sprite, rt))
    {
        pt.x = (rt.left + rt.right) / 2;
        pt.y = (rt.top + rt.bottom) / 2;
        return TRUE;
    }

    return FALSE;
}

BOOL CSpriteLow::Intersected(CSpriteLow *Sprite, RECT &rt)
{

	// Checks for collision with another sprite
	// rt is filled with the union rectangle

    m_Rect1->left = (int) GetX() + m_iShrinkX;
    m_Rect1->top = (int) GetY() + m_iShrinkY;
    m_Rect1->right = (int) GetX() + ImageWidth() - m_iShrinkX;
    m_Rect1->bottom = (int) GetY() + ImageHeight() - m_iShrinkY;

    m_Rect2->left = (int) Sprite->GetX() + Sprite->GetShrinkX();
    m_Rect2->top = (int) Sprite->GetY() + Sprite->GetShrinkY();
    m_Rect2->right = (int) Sprite->GetX() + Sprite->ImageWidth() - Sprite->GetShrinkX();
    m_Rect2->bottom = (int) Sprite->GetY() + Sprite->ImageHeight() - Sprite->GetShrinkY();

    if (IntersectRect(m_DestRect, m_Rect1, m_Rect2))
    {
        rt.left = m_DestRect->left;
        rt.right = m_DestRect->right;
        rt.top = m_DestRect->top;
        rt.bottom = m_DestRect->bottom;
        return TRUE;
    }

    return FALSE;
}


BOOL CSpriteLow::IntersectedRect(RECT *rect1)
{
	// checks for sprite collision with rect2

    m_Rect1->left = (int) GetX() + m_iShrinkX;
    m_Rect1->top = (int) GetY() + m_iShrinkY;
    m_Rect1->right = (int) GetX() + ImageWidth() - m_iShrinkX;
    m_Rect1->bottom = (int) GetY() + ImageHeight() - m_iShrinkY;

    if (IntersectRect(m_DestRect, m_Rect1, rect1))
    {
        return TRUE;
    }

    return FALSE;
}